use crate::DataCommands;
use indicatif::{ProgressBar, ProgressStyle};
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;

#[derive(Debug, Serialize, Deserialize)]
pub struct CsvInfo {
    pub rows: usize,
    pub columns: usize,
    pub headers: Vec<String>,
    pub sample_data: Vec<Vec<String>>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct JsonInfo {
    pub is_valid: bool,
    pub structure: String,
    pub keys: Vec<String>,
    pub size: usize,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct XmlInfo {
    pub is_valid: bool,
    pub root_element: Option<String>,
    pub elements: Vec<String>,
    pub attributes: Vec<String>,
}

pub fn handle_data_commands(command: DataCommands, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    match command {
        DataCommands::Csv { file, operation, filter, format } => {
            handle_csv_operations(&file, &operation, filter.as_deref(), &format, verbose)?;
        },
        DataCommands::Json { file, operation, query } => {
            handle_json_operations(&file, &operation, query.as_deref(), verbose)?;
        },
        DataCommands::Xml { file, operation, query } => {
            handle_xml_operations(&file, &operation, query.as_deref(), verbose)?;
        },
    }
    Ok(())
}

fn handle_csv_operations(
    file: &Path, 
    operation: &str, 
    filter: Option<&str>, 
    format: &str, 
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("处理 CSV 文件...");
    
    let mut reader = csv::Reader::from_path(file)?;
    let headers = reader.headers()?.clone();
    let mut records = Vec::new();
    
    for result in reader.records() {
        let record = result?;
        records.push(record);
    }
    
    pb.finish_with_message("✅ CSV 处理完成");
    
    match operation {
        "info" => {
            let info = CsvInfo {
                rows: records.len(),
                columns: headers.len(),
                headers: headers.iter().map(|h| h.to_string()).collect(),
                sample_data: records.iter().take(5).map(|r| r.iter().map(|f| f.to_string()).collect()).collect(),
            };
            print_csv_info(&info, format);
        },
        "filter" => {
            if let Some(filter_expr) = filter {
                filter_csv_records(&records, &headers, filter_expr, format, verbose)?;
            } else {
                return Err("过滤操作需要指定过滤条件".into());
            }
        },
        "convert" => {
            convert_csv_to_format(&records, &headers, format, verbose)?;
        },
        "merge" => {
            return Err("合并操作需要多个文件，当前版本暂不支持".into());
        },
        _ => return Err("不支持的 CSV 操作".into()),
    }
    
    Ok(())
}

fn handle_json_operations(
    file: &Path, 
    operation: &str, 
    query: Option<&str>, 
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("处理 JSON 文件...");
    
    let contents = fs::read_to_string(file)?;
    let json_value: serde_json::Value = serde_json::from_str(&contents)?;
    
    pb.finish_with_message("✅ JSON 处理完成");
    
    match operation {
        "validate" => {
            let info = JsonInfo {
                is_valid: true,
                structure: get_json_structure(&json_value),
                keys: get_json_keys(&json_value),
                size: contents.len(),
            };
            print_json_info(&info);
        },
        "format" => {
            let formatted = serde_json::to_string_pretty(&json_value)?;
            println!("{}", formatted);
        },
        "query" => {
            if let Some(jsonpath) = query {
                query_json(&json_value, jsonpath, verbose)?;
            } else {
                return Err("查询操作需要指定 JSONPath".into());
            }
        },
        "merge" => {
            return Err("合并操作需要多个文件，当前版本暂不支持".into());
        },
        _ => return Err("不支持的 JSON 操作".into()),
    }
    
    Ok(())
}

fn handle_xml_operations(
    file: &Path, 
    operation: &str, 
    query: Option<&str>, 
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    let pb = ProgressBar::new_spinner();
    pb.set_message("处理 XML 文件...");
    
    let contents = fs::read_to_string(file)?;
    let mut reader = quick_xml::Reader::from_str(&contents);
    reader.trim_text(true);
    
    let mut is_valid = true;
    let mut root_element = None;
    let mut elements = Vec::new();
    let mut attributes = Vec::new();
    
    let mut buf = Vec::new();
    loop {
        match reader.read_event_into(&mut buf) {
            Ok(quick_xml::events::Event::Start(ref e)) => {
                let name = String::from_utf8_lossy(e.name().as_ref());
                if root_element.is_none() {
                    root_element = Some(name.to_string());
                }
                elements.push(name.to_string());
                
                for attr in e.attributes() {
                    if let Ok(attr) = attr {
                        let attr_name = String::from_utf8_lossy(attr.key.as_ref());
                        attributes.push(attr_name.to_string());
                    }
                }
            },
            Ok(quick_xml::events::Event::Eof) => break,
            Ok(_) => {},
            Err(_) => {
                is_valid = false;
                break;
            }
        }
        buf.clear();
    }
    
    pb.finish_with_message("✅ XML 处理完成");
    
    match operation {
        "validate" => {
            let info = XmlInfo {
                is_valid,
                root_element,
                elements,
                attributes,
            };
            print_xml_info(&info);
        },
        "format" => {
            if is_valid {
                let formatted = format_xml(&contents)?;
                println!("{}", formatted);
            } else {
                return Err("XML 文件格式无效".into());
            }
        },
        "query" => {
            if let Some(xpath) = query {
                query_xml(&contents, xpath, verbose)?;
            } else {
                return Err("查询操作需要指定 XPath".into());
            }
        },
        "convert" => {
            convert_xml_to_json(&contents, verbose)?;
        },
        _ => return Err("不支持的 XML 操作".into()),
    }
    
    Ok(())
}

fn print_csv_info(info: &CsvInfo, format: &str) {
    match format {
        "json" => {
            println!("{}", serde_json::to_string_pretty(info).unwrap());
        },
        "xml" => {
            println!("{}", quick_xml::se::to_string(info).unwrap());
        },
        "yaml" => {
            println!("{}", serde_yaml::to_string(info).unwrap());
        },
        _ => {
            println!("📊 CSV 文件信息:");
            println!("  行数: {}", info.rows);
            println!("  列数: {}", info.columns);
            println!("  列名: {:?}", info.headers);
            println!("  示例数据:");
            for (i, row) in info.sample_data.iter().enumerate() {
                println!("    行 {}: {:?}", i + 1, row);
            }
        },
    }
}

fn print_json_info(info: &JsonInfo) {
    println!("📊 JSON 文件信息:");
    println!("  有效性: {}", if info.is_valid { "✅ 有效" } else { "❌ 无效" });
    println!("  结构: {}", info.structure);
    println!("  键: {:?}", info.keys);
    println!("  大小: {} 字节", info.size);
}

fn print_xml_info(info: &XmlInfo) {
    println!("📊 XML 文件信息:");
    println!("  有效性: {}", if info.is_valid { "✅ 有效" } else { "❌ 无效" });
    if let Some(ref root) = info.root_element {
        println!("  根元素: {}", root);
    }
    println!("  元素: {:?}", info.elements);
    println!("  属性: {:?}", info.attributes);
}

fn filter_csv_records(
    records: &[csv::StringRecord], 
    headers: &csv::StringRecord, 
    filter_expr: &str, 
    format: &str, 
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    // 简单的过滤实现
    let filtered: Vec<_> = records.iter()
        .filter(|record| {
            // 这里可以实现更复杂的过滤逻辑
            record.iter().any(|field| field.contains(filter_expr))
        })
        .collect();
    
    if verbose {
        println!("过滤结果: {} 条记录", filtered.len());
    }
    
    match format {
        "json" => {
            let mut result = Vec::new();
            for record in filtered {
                let mut obj = serde_json::Map::new();
                for (i, field) in record.iter().enumerate() {
                    if let Some(header) = headers.get(i) {
                        obj.insert(header.to_string(), serde_json::Value::String(field.to_string()));
                    }
                }
                result.push(serde_json::Value::Object(obj));
            }
            println!("{}", serde_json::to_string_pretty(&result)?);
        },
        _ => {
            for record in filtered {
                println!("{}", record.iter().collect::<Vec<_>>().join(","));
            }
        },
    }
    
    Ok(())
}

fn convert_csv_to_format(
    records: &[csv::StringRecord], 
    headers: &csv::StringRecord, 
    format: &str, 
    verbose: bool
) -> Result<(), Box<dyn std::error::Error>> {
    match format {
        "json" => {
            let mut result = Vec::new();
            for record in records {
                let mut obj = serde_json::Map::new();
                for (i, field) in record.iter().enumerate() {
                    if let Some(header) = headers.get(i) {
                        obj.insert(header.to_string(), serde_json::Value::String(field.to_string()));
                    }
                }
                result.push(serde_json::Value::Object(obj));
            }
            println!("{}", serde_json::to_string_pretty(&result)?);
        },
        "xml" => {
            println!("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            println!("<data>");
            for record in records {
                println!("  <record>");
                for (i, field) in record.iter().enumerate() {
                    if let Some(header) = headers.get(i) {
                        println!("    <{}>{}</{}>", header, field, header);
                    }
                }
                println!("  </record>");
            }
            println!("</data>");
        },
        "yaml" => {
            let mut result = Vec::new();
            for record in records {
                let mut obj = serde_yaml::Mapping::new();
                for (i, field) in record.iter().enumerate() {
                    if let Some(header) = headers.get(i) {
                        obj.insert(
                            serde_yaml::Value::String(header.to_string()),
                            serde_yaml::Value::String(field.to_string())
                        );
                    }
                }
                result.push(serde_yaml::Value::Mapping(obj));
            }
            println!("{}", serde_yaml::to_string(&result)?);
        },
        _ => return Err("不支持的转换格式".into()),
    }
    
    if verbose {
        println!("✅ 转换完成，共处理 {} 条记录", records.len());
    }
    
    Ok(())
}

fn get_json_structure(value: &serde_json::Value) -> String {
    match value {
        serde_json::Value::Object(_) => "Object".to_string(),
        serde_json::Value::Array(_) => "Array".to_string(),
        serde_json::Value::String(_) => "String".to_string(),
        serde_json::Value::Number(_) => "Number".to_string(),
        serde_json::Value::Bool(_) => "Boolean".to_string(),
        serde_json::Value::Null => "Null".to_string(),
    }
}

fn get_json_keys(value: &serde_json::Value) -> Vec<String> {
    match value {
        serde_json::Value::Object(map) => map.keys().map(|k| k.clone()).collect(),
        _ => Vec::new(),
    }
}

fn query_json(value: &serde_json::Value, jsonpath: &str, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    // 简单的 JSONPath 查询实现
    if jsonpath.starts_with("$.") {
        let path = &jsonpath[2..];
        if let Some(result) = value.get(path) {
            println!("{}", serde_json::to_string_pretty(result)?);
        } else {
            println!("未找到路径: {}", path);
        }
    } else {
        return Err("不支持的 JSONPath 格式".into());
    }
    
    if verbose {
        println!("✅ 查询完成");
    }
    
    Ok(())
}

fn format_xml(xml: &str) -> Result<String, Box<dyn std::error::Error>> {
    // 简单的 XML 格式化
    let mut formatted = String::new();
    let mut indent = 0;
    let mut in_tag = false;
    
    for ch in xml.chars() {
        match ch {
            '<' => {
                if in_tag {
                    formatted.push('\n');
                    formatted.push_str(&"  ".repeat(indent));
                }
                formatted.push(ch);
                in_tag = true;
            },
            '>' => {
                formatted.push(ch);
                in_tag = false;
                if formatted.ends_with("/>") {
                    formatted.push('\n');
                } else if formatted.ends_with("</") {
                    indent = indent.saturating_sub(1);
                    formatted.push('\n');
                } else {
                    indent += 1;
                    formatted.push('\n');
                }
            },
            _ => {
                if in_tag {
                    formatted.push(ch);
                } else {
                    formatted.push(ch);
                }
            },
        }
    }
    
    Ok(formatted)
}

fn query_xml(xml: &str, xpath: &str, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    // 简单的 XPath 查询实现
    if xpath.starts_with("/") {
        let path = &xpath[1..];
        if let Some(result) = find_xml_element(xml, path) {
            println!("{}", result);
        } else {
            println!("未找到元素: {}", path);
        }
    } else {
        return Err("不支持的 XPath 格式".into());
    }
    
    if verbose {
        println!("✅ 查询完成");
    }
    
    Ok(())
}

fn find_xml_element(xml: &str, path: &str) -> Option<String> {
    // 简单的 XML 元素查找
    let pattern = format!("<{}>", path);
    if let Some(start) = xml.find(&pattern) {
        let start = start + pattern.len();
        let end_pattern = format!("</{}>", path);
        if let Some(end) = xml[start..].find(&end_pattern) {
            return Some(xml[start..start + end].to_string());
        }
    }
    None
}

fn convert_xml_to_json(xml: &str, verbose: bool) -> Result<(), Box<dyn std::error::Error>> {
    // 简单的 XML 到 JSON 转换
    let mut json_obj = serde_json::Map::new();
    
    // 这里可以实现更复杂的 XML 到 JSON 转换逻辑
    json_obj.insert("xml_content".to_string(), serde_json::Value::String(xml.to_string()));
    
    println!("{}", serde_json::to_string_pretty(&serde_json::Value::Object(json_obj))?);
    
    if verbose {
        println!("✅ 转换完成");
    }
    
    Ok(())
}


